package org.letva.toink.blog.service.impl;

import com.google.inject.Inject;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.letva.toink.blog.model.Comment;
import org.letva.toink.blog.model.Post;
import org.letva.toink.blog.model.User;
import org.letva.toink.blog.service.BlogService;
import org.letva.toink.dao.GenericDao;
import org.letva.toink.util.HibernateUtil;

import java.util.ArrayList;
import java.util.List;

public class BlogServiceImpl implements BlogService {
    @Inject
    GenericDao genericDao;

    // ---------------------------- User registration/login methods
    @Override
    public void login() {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void logout() {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public User register(User user) {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public boolean isLoggedIn() {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

    // --------------------------- Post CRUD operations
    @Override
    public void addPost(Post post) {
        genericDao.saveOrUpdate(post);
    }

    @Override
    public Post getPost(Long postId) {
        return genericDao.getById(postId, Post.class);
    }

    @Override
    public void updatePost(Post post) {
        genericDao.saveOrUpdate(post);
    }

    @Override
    public void deletePost(Post post) {
        genericDao.delete(post);
    }

    @Override
    public List<Post> getPosts(User user, int fromCount, int toCount) {
        Criteria criteria = HibernateUtil.getSession().createCriteria(Post.class);
        criteria.setFirstResult(fromCount);
        criteria.setMaxResults(toCount - fromCount + 1);
        criteria.add(Restrictions.eq("user", user));
        return criteria.list();
    }

    @Override
    public List<Post> getPosts(int fromCount, int toCount) {
        Criteria criteria = HibernateUtil.getSession().createCriteria(Post.class);
        criteria.setFirstResult(fromCount);
        criteria.setMaxResults(toCount - fromCount + 1);
        return criteria.list();
    }

    @Override
    public List<Post> getNewestPosts(int count) {
        Criteria criteria = HibernateUtil.getSession().createCriteria(Post.class);
        criteria.setMaxResults(count);
        criteria.addOrder(Order.desc("datetime"));
        return criteria.list();
    }

    @Override
    public List<Post> getNewestPosts(User user, int count) {
        Criteria criteria = HibernateUtil.getSession().createCriteria(Post.class);
        criteria.setMaxResults(count);
        criteria.addOrder(Order.asc("datetime"));
        criteria.add(Restrictions.eq("user", user));
        return criteria.list();
    }

    @Override
    public void addComment(Long postId, Comment comment) {
        Post post = genericDao.getById(postId, Post.class);
        if (post.getComments() == null) {
            post.setComments(new ArrayList<Comment>());
        }
        post.getComments().add(comment);
        comment.setPost(post);
        genericDao.saveOrUpdate(post);
    }

    // --------------------------- Comment CRUD operations
    @Override
    public void addComment(Post post, Comment comment) {
        if (post.getComments() == null) {
            post.setComments(new ArrayList<Comment>());
        }
        post.getComments().add(comment);
        comment.setPost(post);
        genericDao.saveOrUpdate(post);
    }

    @Override
    public Comment getComment(Long commentId) {
        return genericDao.getById(commentId, Comment.class);
    }

    @Override
    public void updateComment(Comment comment) {
        genericDao.saveOrUpdate(comment);
    }

    @Override
    public void deleteComment(Comment comment) {
        genericDao.delete(comment);
    }

    // ---------------------------- Retrieve Comments
    @Override
    public List<Comment> getPostComments(Long postId, int fromCount, int toCount) {
        Criteria criteria = HibernateUtil.getSession().createCriteria(Comment.class);
        criteria.setFirstResult(fromCount);
        criteria.setMaxResults(toCount - fromCount + 1);
        criteria.add(Restrictions.eq("post.id", postId));
        return criteria.list();
    }

    @Override
    public List<Comment> getPostComments(Post post, int fromCount, int toCount) {
        Criteria criteria = HibernateUtil.getSession().createCriteria(Comment.class);
        criteria.setFirstResult(fromCount);
        criteria.setMaxResults(toCount - fromCount + 1);
        criteria.add(Restrictions.eq("post", post));
        return criteria.list();
    }

    @Override
    public List<Comment> getUserComments(Long userId, int fromCount, int toCount) {
        Criteria criteria = HibernateUtil.getSession().createCriteria(Comment.class);
        criteria.setFirstResult(fromCount);
        criteria.setMaxResults(toCount - fromCount + 1);
        criteria.add(Restrictions.eq("user.id", userId));
        return criteria.list();
    }

    @Override
    public List<Comment> getUserComments(User user, int fromCount, int toCount) {
        Criteria criteria = HibernateUtil.getSession().createCriteria(Comment.class);
        criteria.setFirstResult(fromCount);
        criteria.setMaxResults(toCount - fromCount + 1);
        criteria.add(Restrictions.eq("user", user));
        return criteria.list();
    }
}
